#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <unistd.h>
#include <signal.h>

Display *display = NULL;

void cleanup() {
    if (display) {
        XCloseDisplay(display);
        display = NULL;
    }
}

void handle_signal(int sig) {
    //printf("\n收到信号 %d，退出程序...\n", sig);
    cleanup();
    exit(0);
}

int main() {
    // 设置信号处理
    signal(SIGINT, handle_signal);
    signal(SIGTERM, handle_signal);
    atexit(cleanup);

    // 打开X11显示连接
    display = XOpenDisplay(NULL);
    if (display == NULL) {
        //fprintf(stderr, "无法打开X11显示连接\n");
        return 1;
    }

    // 初始化XKB扩展
    int opcode, error, major = XkbMajorVersion, minor = XkbMinorVersion;
    int xkb_event_type;
    if (!XkbQueryExtension(display, &opcode, &xkb_event_type, &error, &major, &minor)) {
        //fprintf(stderr, "XKB扩展不可用\n");
        return 1;
    }

    // 请求XKB状态通知
    unsigned long bits = XkbStateNotifyMask;
    if (!XkbSelectEvents(display, XkbUseCoreKbd, bits, bits)) {
        //fprintf(stderr, "无法请求XKB状态通知\n");
        return 1;
    }

    // 获取初始状态
    XkbStateRec state;
    XkbGetState(display, XkbUseCoreKbd, &state);
    int caps_lock_state = state.locked_mods & LockMask;
    int num_lock_state = state.locked_mods & Mod2Mask;

    //printf("监控键盘大小写状态变化...\n");
    //printf("初始状态 - CapsLock: %s, NumLock: %s\n", caps_lock_state ? "开" : "关", num_lock_state ? "开" : "关");

    // 设置文件描述符用于select
    int x11_fd = ConnectionNumber(display);
    fd_set in_fds;
    struct timeval tv;
    
    //printf("程序已启动，等待键盘状态变化...\n");

    while (1) {
        FD_ZERO(&in_fds);
        FD_SET(x11_fd, &in_fds);
        
        // 设置超时时间(可以设置为NULL表示无限等待)
        tv.tv_usec = 0;
        tv.tv_sec = 1;
        
        // 等待X11事件
        int num_ready = select(x11_fd + 1, &in_fds, NULL, NULL, &tv);
        
        if (num_ready < 0) {
            perror("select错误");
            break;
        } else if (num_ready == 0) {
            // 超时，可以在这里执行定期检查或其他操作
            continue;
        }
        
        // 处理X11事件
        while (XPending(display)) {
            XEvent event;
            XNextEvent(display, &event);
            
            if (event.type == xkb_event_type) {
                XkbEvent *xkb_event = (XkbEvent *)&event;
                if (xkb_event->any.xkb_type == XkbStateNotify) {
                    int new_caps = xkb_event->state.locked_mods & LockMask;
                    int new_num = xkb_event->state.locked_mods & Mod2Mask;
                    
                    // 检查CapsLock状态是否变化
                    if (new_caps != caps_lock_state) {
                        caps_lock_state = new_caps;
                        //printf("CapsLock状态改变: %s\n", caps_lock_state ? "开" : "关");
                        
                        // 执行dbus-send命令
                        char command[256];
                        snprintf(command, sizeof(command), "awesome-client \"require('widgets.caps'):%s()\"", caps_lock_state ? "on" : "off");
                        
                        system(command);
                    }
                    
                    // 可选: 监控NumLock状态
                    //if (new_num != num_lock_state) {
                    //    num_lock_state = new_num;
                    //    printf("NumLock状态改变: %s\n", num_lock_state ? "开" : "关");
                    //}
                }
            }
        }
    }

    return 0;
}
